package se.webbzon.boltzmann.game.object.pickup;

import java.awt.Color;
import java.util.Collection;

import se.webbzon.boltzmann.collector.Collector;
import se.webbzon.boltzmann.effect.StarEffect;
import se.webbzon.boltzmann.game.object.player.AbstractPlayerCharacter;
import se.webbzon.boltzmann.player.Player;
import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.boltzmann.sound.SoundUtils;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldeditor.DeflatableWorldObject;
import se.webbzon.oschi01.worldeditor.WorldObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.XYPlaneAppearance3D;

public class Restoration extends WorldStaticObject implements DeflatableWorldObject {
	
	// The name of this deflatable world object
	public static final String worldObjectName = "restoration";
	
	// The default cooldown of the restoration
	private static final int cooldown = 180, effectCooldown = 2;
	
	// The range of this pickup
	private static final double pickupDistance = 16;
	
	// The shadow of this restoration
	private final RestorationShadow shadow;
	
	// A collector used to track all the players
	private Collector<AbstractPlayerCharacter> players;
	
	// The time left until cooldown is complete and the
	// time left until the effect cooldown is complete
	private int t, te;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public Restoration() {
		super(WorldObject.onCreate + WorldObject.onStep + WorldObject.onDestroy, createAppearance());
		super.setSize(16, 16, 16);
		shadow = new RestorationShadow(this);
		t = 0;
		te = 0;
	}
	
	/*============================================================
	Public Methods
	============================================================*/

	@Override public void setRotation(double x, double y, double z, double angle) {};

	@Override public void setSize(double width, double height, double depth) {};

	@Override public void onCreate(WorldArea world) {
		players = Collector.getCollector(world, AbstractPlayerCharacter.class);
		shadow.launch(world);
	}

	@Override public void onStep(WorldArea world) {
		if (t == 0) {
			Collection<AbstractPlayerCharacter> playerCollection = players.getInstances();
			for (AbstractPlayerCharacter player : playerCollection) {
				if (distanceTo(player) < pickupDistance) {
					Player p = player.getPlayer();
					p.getHealth().setHealth(p.getHealth().getMaxHealth());
					p.getEnergy().setEnergy(p.getEnergy().getMaxEnergy());
					t = cooldown;
					SoundUtils.playSound("health_pickup");
				}
			}
			if (te == 0) {
				new StarEffect(StarEffect.LIFTOFF+StarEffect.FADE,this,30,Color.white,1).launch(world);
				te = effectCooldown;
			} else if (te > 0)
				te--;
		} else if (t > 0) {
			SimpleAppearance3D appearance = (SimpleAppearance3D) getAppearance();
			appearance.setTransparency(1 - 0.75f * (1 - t / (float) cooldown));
			t--;
		}
	}

	@Override public void onDestroy(WorldArea world) {
		players = null;
		shadow.terminate(world);
	}
	
	@Override public String getName() {
		return worldObjectName;
	}

	@Override public WorldObjectDeflation getDeflation() {
		return new RestorationDeflation(0,this);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the appearance of the restoration point. **/
	private static final Appearance3D createAppearance() {
		SimpleAppearance3D appearance = new XYPlaneAppearance3D(1,SimpleAppearance3D.TRANSPARENCY,false);
		appearance.setTextureSet(Resources.getTextureSet("object_health"));
		appearance.setTransparency(0.25f);
		appearance.setTextureSpeed(0.5);
		return appearance;
	}

}
